#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Created on 2011/03/10

@author: Administrator
'''
import math
from core.EvaluatedFriends import EvaluatedFriendsClass
from google.appengine.ext import db
from util.models import PlayerInfo
from util.models import QuantityTitle
from util.models import QualityTitle
from util.models import LuckyItem

class PlayerInfoClass():
    def __init__(self):
        self.UPPER_LEVEL=3.5
        self.MAX_EVALUATION=5
        self.GOOD_PARTNER_TIME = 5;
        self.GOOD_FRIEND_TIME = 3;
        self.SAME_TITLE_FRIEND_TIME = 1;
        self.EVALUATION_TABLE_MAX = 5;
        self.GOOD_FRIEND_MAX=3;
        self.GOOD_PARTNER_MAX=1;
        self.GQL_IN_FILTER_MAX=28;

###    def setGender(self,myID,gender):
###        myIDs = PlayerInfo.gql('WHERE playerID=:1 LIMIT 1',myID)
###        myID=myIDs.get()
###        myID.gender=int(gender)
###        db.put(myID)
            
    def updatePlayersPoints(self,playersPoint,playersPlayNum):
        for playerID in playersPoint:
            playerInfo = self.getPlayerInfo(playerID)
            categoryPoints = playerInfo.categoryPoints
            categoryPlayNums = playerInfo.categoryPlayNums
            i=0
            ## distribute the point based on rank
            for categoryPoint in categoryPoints:
                oldPoint = categoryPoint * categoryPlayNums[i]
                playNum = categoryPlayNums[i]
                newNum = playNum+playersPlayNum[playerID][i]
                newPoint = (oldPoint + playersPoint[playerID][i]) / newNum
                playerInfo.categoryPoints[i]=float(newPoint)
                playerInfo.categoryPlayNums[i]=newNum            
                playerInfo.totalPoint+=playersPoint[playerID][i]
                playerInfo.evaluatedTime+=1
                i+=1
            

            playerInfo.qualityTitle=self.updateQualityTitle(playerInfo.categoryPoints)
            playerInfo.quantityTitle=self.updateQuantityTitle(playerInfo.totalPoint)
        
            db.put(playerInfo)
            
    def updateQualityTitle(self,categoryPoints):
        maxCategoryPoint=max(categoryPoints)
        maxIndex = categoryPoints.index(maxCategoryPoint)
        level = 0
        if maxCategoryPoint >= self.UPPER_LEVEL:
            level = 1;
        g_list = QualityTitle.gql('WHERE titleLevel=:1 AND titleCategory=:2 ORDER BY titleID LIMIT 1',level,maxIndex)
        qlTitle = g_list.get()
        return qlTitle.titleName
    
    def updateQuantityTitle(self,totalPoint):
        g_list = QuantityTitle.gql('WHERE requiredPoint<=:1 ORDER BY requiredPoint DESC LIMIT 1',totalPoint)
        qnTitle= g_list.get()
        return qnTitle.titleName
    
    def getMyInfo(self,myID):
        myInfo={}
        synastryList = {}
        # get my playerInfo
        playerInfo = self.getPlayerInfo(myID)
        myInfo['playerInfo']=playerInfo
        
        # create fortuneList
        fortuneList = self.createFortuneList(playerInfo.qualityTitle, playerInfo.quantityTitle)
        fortuneList['luckyItem']=self.getLuckyItem(fortuneList['qnTitleID'],fortuneList['qlTitleID'])  
        myInfo['fortuneList']=fortuneList.copy() 

        # create synastryList
        ef = EvaluatedFriendsClass()
        evaluatedFriends = ef.getEvaluatedFriends(myID)
        splitedFriends=self.splitedEvaluatedFriends(evaluatedFriends.evaluatedFriendsList)
        synastryList["goodPartnerName"] = {'needTime':self.GOOD_PARTNER_TIME,'friendsIDList':self.createGoodPartners(playerInfo.quantityTitle,playerInfo.qualityTitle, splitedFriends)}
 
        # update good friend
        synastryList["goodFriendName"] = {'needTime':self.GOOD_FRIEND_TIME,'friendsIDList':self.createGoodFriends(playerInfo.qualityTitle,splitedFriends)}

        # update same title friend
        synastryList["sameTitleFriendName"] = {'needTime':self.SAME_TITLE_FRIEND_TIME,'friendsIDList':self.createSameTitleFriends(playerInfo.qualityTitle,splitedFriends)}
        
        myInfo['synastryList']=synastryList.copy()
        return myInfo
    
    ## when the user has more than 30 evaluated friends, split evaluated friends to make some group to avoid GAE IN filter limitation which allows max queries is 30
    #  At present, 1 group consists of GQL_IN_FILTER_MAX friends
    #   
    def splitedEvaluatedFriends(self,evaluatedFriendsList):
        splitedFriends=[]
        startIndex=0
        endIndex=self.GQL_IN_FILTER_MAX
        time=math.ceil(float(len(evaluatedFriendsList))/self.GQL_IN_FILTER_MAX)
        i=0
        for i in range(int(time)):
            startIndex=i*self.GQL_IN_FILTER_MAX
            endIndex=(i+1)*self.GQL_IN_FILTER_MAX-1
            if i==(time-1):
                splitedFriends.append(evaluatedFriendsList[startIndex:])
            else:
                splitedFriends.append(evaluatedFriendsList[startIndex:endIndex])
            i+=1
        
        return splitedFriends
 
    def getLuckyItem(self,qnTitleID,qlTitleID):
        g_list = LuckyItem.gql("WHERE qnTitleID=:1 AND qlTitleID=:2",qnTitleID,qlTitleID)
        item = g_list.get()
        if(item==None):
            return ""
        else:
            return item.itemName
    
    def getPlayerInfo(self,playerID):
        playerInfos = PlayerInfo.gql('WHERE playerID = :1', playerID)
        playerInfo=playerInfos.get()
        ## if the player information doesn't exist, register initialize information
        if playerInfo==None:
            categoryPoints = [3.0, 3.0, 3.0, 3.0, 3.0]
            categoryPlayNums = [1, 1, 1, 1, 1]
            playerInfo = PlayerInfo(playerID=playerID,gender=0,evaluatedTime=0,totalPoint=15,quantityTitle=u'普通の',qualityTitle=u'うさぎ',categoryPoints=categoryPoints,categoryPlayNums=categoryPlayNums,friendsNum=0)
            playerInfo.put()
        return playerInfo 
       
    def getSynastryList(self):
        return self.synastryList
    
    def getEvaluations(self):
        return self.evaluationsList
    
    def getFortuneList(self):
        return self.fortunList 
        
    def createFortuneList(self,qualityTitle,quantityTitle):
        fortuneList={}
        qlTitles = QualityTitle.gql('WHERE titleName=:1 LIMIT 1',qualityTitle)
        qlTitle = qlTitles.get()
        
        if (qlTitle==None):
            fortuneList["fortuneContent"]=""
            fortuneList["qlTitleName"]=""
            fortuneList["qlTitleID"]=""
        else:
            fortuneList["fortuneContent"]=qlTitle.fortuneContent
            fortuneList["qlTitleName"]=qlTitle.titleName
            fortuneList["oppositeTitle"]=qlTitle.oppositeTitle
            fortuneList["qlTitleID"]=qlTitle.titleID
        
        gnTitles = QuantityTitle.gql('WHERE titleName=:1 LIMIT 1',quantityTitle)
        qnTitle= gnTitles.get()
        if(qnTitle==None):
            fortuneList["qnTitleName"]=""
            fortuneList["qnTitleID"]=""
        else:
            fortuneList["qnTitleName"]=qnTitle.titleName
            fortuneList["qnTitleID"]=qnTitle.titleID     
        
        return fortuneList 
    
    def createSameTitleFriends(self,qlTitle,evaluatedFriends):
        sameFriends=[]
        if len(evaluatedFriends)!=0:
            for evaluatedFriendsList in evaluatedFriends:
                querySame = PlayerInfo.gql('WHERE qualityTitle=:1 AND playerID IN :2 LIMIT 3',qlTitle,evaluatedFriendsList)
                for player in querySame:
                    sameFriends.append(player.playerID)
                    if len(sameFriends)==self.GOOD_FRIEND_MAX:
                        return sameFriends
        return sameFriends   

    def createGoodPartners(self,qnTitle,qlTitle,evaluatedFriends):
        goodPartners=[]
        if len(evaluatedFriends)!=0:
            qualityTitles = QualityTitle.gql('WHERE titleName=:1',qlTitle)
            qualityTitle = qualityTitles.get()
            if qualityTitle != None:                
                for evaluatedFriendsList in evaluatedFriends:
                    queryPlayer = PlayerInfo.gql('WHERE quantityTitle=:1 AND qualityTitle=:2 AND playerID IN :3 ORDER BY totalPoint DESC LIMIT 1',qnTitle,qualityTitle.oppositeTitle,evaluatedFriendsList)
                    for player in queryPlayer:
                        goodPartners.append(player.playerID)
                        if len(goodPartners)==self.GOOD_PARTNER_MAX:
                            return goodPartners
        return goodPartners  
    

    def createGoodFriends(self,qlTitle,evaluatedFriends):
        goodFriends=[];
        if len(evaluatedFriends)!=0:
            qualityTitles = QualityTitle.gql('WHERE titleName=:1',qlTitle)
            qualityTitle = qualityTitles.get()
            if qualityTitle != None:             
                for evaluatedFriendsList in evaluatedFriends:
                    gueryPlayer = PlayerInfo.gql('WHERE qualityTitle=:1 AND playerID IN :2 LIMIT 3',qualityTitle.oppositeTitle,evaluatedFriendsList)
                    for player in gueryPlayer:
                        goodFriends.append(player.playerID)
                        if len(goodFriends)==self.GOOD_FRIEND_MAX:
                            return goodFriends
        return goodFriends
